﻿using ArduinoAnalyzer.LexicalAnalysis;
using ArduinoAnalyzer.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ArduinoAnalyzer.SyntaticAnalysis
{
    public class SyntacticAnalyzer
    {
        #region Constructors

        public SyntacticAnalyzer(IEnumerator<Token> enumerator)
        {
            _enumrator = enumerator;
        }

        #endregion

        #region Private Members

        private IEnumerator<Token> _enumrator;
        private List<Token> _tokens = new List<Token>();
        private int _currentIndex = -1;
        private Token _current;
        private bool _end = false;

        #endregion

        #region Public Methods

        public bool Validate()
        {
            this.MoveNext();
            var program = Program();

            return program && _end;
        }

        #endregion

        #region Private Methods

        private bool Program()
        {
            if (_end)
                return false;

            //if (DeclarationsSet())
            //    return true;
            if (DS())
                return true;

            return false;
        }

        private bool Modifier()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Static)
            {
                this.MoveNext();
                return true;
            }

            return false;
        }

        private bool IdentifierDeclarationsSetLine()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Comma)
            {
                this.MoveNext();
                if (IdentifierDeclaration())
                {
                    if (IdentifierDeclarationsSetLine())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Declaration()
        {
            if (_end)
                return true;

            if (!_end && _current.Type == TokenType.Assignment)
            {
                this.MoveNext();
                if (Expression0())
                    return true;

                return false;
            }

            return true;
        }

        private bool IdentifierDeclaration()
        {
            if (!_end && _current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (!_end && _current.Type == TokenType.Assignment)
                {
                    this.MoveNext();
                    if (Expression0())
                        return true;

                    return false;
                }

                return true;
            }

            return false;
        }

        private bool ConstDeclaration()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Assignment)
            {
                this.MoveNext();
                if (Expression0())
                    return true;

                return false;
            }

            return false;
        }

        private bool FunctionDeclaration()
        {
            if (ParametersSetOrEmpty())
            {
                if (_end)
                    return false;

                if (_current.Type == TokenType.CloseParentheses)
                {
                    this.MoveNext();
                    if (_end)
                        return false;

                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    if (_current.Type == TokenType.OpenBraces)
                    {
                        this.MoveNext();

                        if (CommandsSet())
                        {
                            if (_end)
                                return false;

                            if (_current.Type == TokenType.CloseBraces)
                            {
                                this.MoveNext();
                                return true;
                            }

                            return false;
                        }

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool Type()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Byte ||
                _current.Type == TokenType.Int ||
                _current.Type == TokenType.Word ||
                _current.Type == TokenType.Short ||
                _current.Type == TokenType.Long ||
                _current.Type == TokenType.Float ||
                _current.Type == TokenType.Double ||
                _current.Type == TokenType.Boolean)
            {
                this.MoveNext();
                return true;
            }

            return false;
        }

        private bool ParametersSetOrEmpty()
        {
            if (_end)
                return true;

            var temp1 = _currentIndex;
            if (ParametersSet())
                return true;

            this.SetCurrent(temp1);

            return true;
        }

        private bool ParametersSet()
        {
            if (_end)
                return false;

            if (Parameter())
            {
                if (_end)
                    return false;

                if (ParameterSetLine())
                    return true;

                return false;
            }

            return false;
        }

        private bool ParameterSetLine()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Comma)
            {
                this.MoveNext();
                if (_end)
                    return false;

                if (Parameter())
                {
                    if (ParameterSetLine())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Parameter()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Unsigned)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Int ||
                    _current.Type == TokenType.Long)
                {
                    this.MoveNext();

                    if (_current.Type == TokenType.Identifier)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (Type())
            {
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    return true;
                }
            }

            return false;
        }

        private bool Command()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.For)
            {
                this.MoveNext();
                if (For())
                    return true;

                return false;
            }

            if (_current.Type == TokenType.While)
            {
                this.MoveNext();
                if (While())
                    return true;

                return false;
            }

            if (_current.Type == TokenType.Do)
            {
                this.MoveNext();
                if (Do())
                {
                    if (WhileDo())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Switch)
            {
                this.MoveNext();
                if (Switch())
                    return true;

                return false;
            }

            if (_current.Type == TokenType.If)
            {
                this.MoveNext();
                if (If())
                    return true;

                return false;
            }

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Increment ||
                    _current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Colon)
                {
                    this.MoveNext();
                    if (Command())
                        return true;

                    return false;
                }

                if (StatementMethodCall())
                {
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Increment ||
                _current.Type == TokenType.Decrement)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GoTo)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Break)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    return true;
                }

                return false;
            }

            if (_current.Type == TokenType.Continue)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    return true;
                }

                return false;
            }

            if (_current.Type == TokenType.Return)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    return true;
                }

                if (Expression0())
                {
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Semicolon)
            {
                this.MoveNext();
                return true;
            }

            if (M())
            {
                if (_current.Type == TokenType.Const)
                {
                    this.MoveNext();

                    if (_current.Type == TokenType.Unsigned)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.Int ||
                            _current.Type == TokenType.Long)
                        {
                            if (CV2())
                                return true;
                            return false;
                        }
                        return false;
                    }

                    if (T())
                    {
                        if (CV2())
                            return true;
                        return false;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        this.MoveNext();
                        if (V2())
                            return true;
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (V2())
                        return true;
                    return false;
                }
            }

            if (_current.Type == TokenType.Const)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        if (CV2())
                            return true;
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (CV2())
                        return true;
                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Unsigned)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Int ||
                    _current.Type == TokenType.Long)
                {
                    this.MoveNext();
                    if (V2())
                        return true;
                    return false;
                }
                return false;
            }

            if (T())
            {
                if (V2())
                    return true;
                return false;
            }

            return false;
        }

        private bool V2()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (D())
                {
                    if (V())
                        return true;
                    return false;
                }
                return false;
            }

            return false;
        }

        private bool CV2()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (CD())
                {
                    if (V())
                        return true;
                    return false;
                }
                return false;
            }

            return false;
        }

        private bool CommandsSet()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.For)
            {
                this.MoveNext();
                if (For())
                {
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.While)
            {
                this.MoveNext();
                if (While())
                {
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Do)
            {
                this.MoveNext();
                if (Do())
                {
                    if (WhileDo())
                    {
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Switch)
            {
                this.MoveNext();
                if (Switch())
                {
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.If)
            {
                this.MoveNext();
                if (If())
                {
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Increment ||
                    _current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Colon)
                {
                    this.MoveNext();
                    if (Command())
                    {
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                if (StatementMethodCall())
                {
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Increment ||
                _current.Type == TokenType.Decrement)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GoTo)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Break)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Continue)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Return)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    if (CommandsSet())
                        return true;

                    return false;
                }

                if (Expression0())
                {
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Semicolon)
            {
                this.MoveNext();
                if (CommandsSet())
                    return true;

                return false;
            }

            if (M())
            {
                if (_current.Type == TokenType.Const)
                {
                    this.MoveNext();

                    if (_current.Type == TokenType.Unsigned)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.Int ||
                            _current.Type == TokenType.Long)
                        {
                            if (CV2())
                            {
                                if (CommandsSet())
                                    return true;
                                return false;
                            }
                            return false;
                        }
                        return false;
                    }

                    if (T())
                    {
                        if (CV2())
                        {
                            if (CommandsSet())
                                return true;
                            return false;
                        }
                        return false;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        this.MoveNext();
                        if (V2())
                        {
                            if (CommandsSet())
                                return true;
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (V2())
                    {
                        if (CommandsSet())
                            return true;
                        return false;
                    }
                    return false;
                }
            }

            if (_current.Type == TokenType.Const)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        if (CV2())
                        {
                            if (CommandsSet())
                                return true;
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (CV2())
                    {
                        if (CommandsSet())
                            return true;
                        return false;
                    }
                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Unsigned)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Int ||
                    _current.Type == TokenType.Long)
                {
                    this.MoveNext();
                    if (V2())
                    {
                        if (CommandsSet())
                            return true;
                        return false;
                    }
                    return false;
                }
                return false;
            }

            if (T())
            {
                if (V2())
                {
                    if (CommandsSet())
                        return true;
                    return false;
                }
                return false;
            }

            return true;
        }

        private bool For()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (StatementSet())
                {
                    if (_current.Type == TokenType.Semicolon)
                    {
                        this.MoveNext();

                        if (_current.Type == TokenType.Semicolon)
                        {
                            this.MoveNext();
                            if (StatementSet())
                            {
                                if (_current.Type == TokenType.CloseParentheses)
                                {
                                    this.MoveNext();
                                    if (_current.Type == TokenType.OpenBraces)
                                    {
                                        this.MoveNext();
                                        if (CommandsSet())
                                        {
                                            if (_current.Type == TokenType.CloseBraces)
                                            {
                                                this.MoveNext();
                                                return true;
                                            }

                                            return false;
                                        }

                                        return false;
                                    }

                                    if (Command())
                                        return true;

                                    return false;
                                }

                                return false;
                            }
                        }

                        if (Expression0())
                        {
                            if (_current.Type == TokenType.Semicolon)
                            {
                                this.MoveNext();
                                if (StatementSet())
                                {
                                    if (_current.Type == TokenType.CloseParentheses)
                                    {
                                        this.MoveNext();
                                        if (_current.Type == TokenType.OpenBraces)
                                        {
                                            this.MoveNext();
                                            if (CommandsSet())
                                            {
                                                if (_current.Type == TokenType.CloseBraces)
                                                {
                                                    this.MoveNext();
                                                    return true;
                                                }

                                                return false;
                                            }

                                            return false;
                                        }

                                        if (Command())
                                            return true;

                                        return false;
                                    }

                                    return false;
                                }

                                return false;
                            }

                            return false;
                        }

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool While()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (Expression0())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();

                        if (_current.Type == TokenType.OpenBraces)
                        {
                            this.MoveNext();
                            if (CommandsSet())
                            {
                                if (_current.Type == TokenType.CloseBraces)
                                {
                                    this.MoveNext();
                                    return true;
                                }

                                return false;
                            }

                            return false;
                        }

                        if (Command())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool Do()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenBraces)
            {
                this.MoveNext();
                if (CommandsSet())
                {
                    if (_current.Type == TokenType.CloseBraces)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (Command())
                return true;

            return false;
        }

        private bool WhileDo()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.While)
            {
                this.MoveNext();
                if (_current.Type == TokenType.OpenParentheses)
                {
                    this.MoveNext();
                    if (Expression0())
                    {
                        if (_current.Type == TokenType.CloseParentheses)
                        {
                            this.MoveNext();
                            if (_current.Type == TokenType.Semicolon)
                            {
                                this.MoveNext();
                                return true;
                            }

                            return false;
                        }

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool Switch()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (Expression0())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.OpenBraces)
                        {
                            this.MoveNext();
                            if (CasesSet())
                            {
                                if (_current.Type == TokenType.CloseBraces)
                                {
                                    this.MoveNext();
                                    return true;
                                }

                                return false;
                            }

                            return false;
                        }

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool CasesSet()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Case)
            {
                this.MoveNext();

                if (Case())
                {
                    if (CasesSet())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Default)
            {
                this.MoveNext();

                if (Default())
                {
                    if (CasesSetLine())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool CasesSetLine()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Case)
            {
                this.MoveNext();
                if (CasesSetLine())
                    return true;

                return false;
            }

            return true;
        }

        private bool Case()
        {
            if (_end)
                return false;

            if (ConstantExpression0())
            {
                if (_current.Type == TokenType.Colon)
                {
                    this.MoveNext();
                    if (Command())
                    {
                        if (CommandsSet())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool Default()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Colon)
            {
                this.MoveNext();
                if (Command())
                {
                    if (CommandsSet())
                        return true;

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool If()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (Expression0())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();
                        if (IfDeclaration())
                        {
                            if (Else())
                                return true;

                            return false;
                        }

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return false;
        }

        private bool Else()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Else)
            {
                this.MoveNext();
                if (IfDeclaration())
                    return true;

                return false;
            }

            return true;
        }

        private bool IfDeclaration()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenBraces)
            {
                this.MoveNext();
                if (CommandsSet())
                {
                    if (_current.Type == TokenType.CloseBraces)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (Command())
                return true;

            return false;
        }

        private bool StatementSet()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Increment ||
                    _current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    if (StatementSetLine())
                        return true;

                    return false;
                }

                if (StatementMethodCall())
                {
                    if (StatementSetLine())
                        return true;
                }

                return false;
            }

            if (_current.Type == TokenType.Increment ||
                _current.Type == TokenType.Decrement)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (StatementSetLine())
                        return true;

                    return false;
                }

                return false;
            }

            if (M())
            {
                if (_current.Type == TokenType.Const)
                {
                    this.MoveNext();

                    if (_current.Type == TokenType.Unsigned)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.Int ||
                            _current.Type == TokenType.Long)
                        {
                            if (CV3())
                                return true;
                            return false;
                        }
                        return false;
                    }

                    if (T())
                    {
                        if (CV3())
                            return true;
                        return false;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        this.MoveNext();
                        if (V3())
                            return true;
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (V3())
                        return true;
                    return false;
                }
            }

            if (_current.Type == TokenType.Const)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        if (CV3())
                            return true;
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (CV3())
                        return true;
                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Unsigned)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Int ||
                    _current.Type == TokenType.Long)
                {
                    this.MoveNext();
                    if (V3())
                        return true;
                    return false;
                }
                return false;
            }

            if (T())
            {
                if (V3())
                    return true;
                return false;
            }

            return true;
        }

        private bool V3()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (D())
                {
                    if (IdentifierDeclarationsSetLine())
                        return true;
                    return false;
                }
                return false;
            }

            return false;
        }

        private bool CV3()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (CD())
                {
                    if (IdentifierDeclarationsSetLine())
                        return true;
                    return false;
                }
                return false;
            }

            return false;
        }

        private bool StatementSetLine()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Comma)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Increment ||
                        _current.Type == TokenType.Decrement)
                    {
                        this.MoveNext();
                        if (StatementSetLine())
                            return true;

                        return false;
                    }

                    if (StatementMethodCall())
                    {
                        if (StatementSetLine())
                            return true;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Increment ||
                    _current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Identifier)
                    {
                        this.MoveNext();
                        if (StatementSetLine())
                            return true;

                        return false;
                    }

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool StatementIdentifierDeclaration()
        {
            if (_end)
                return false;

            if (IdentifierDeclaration())
            {
                if (IdentifierDeclarationsSetLine())
                    return true;
            }

            return false;
        }

        private bool StatementMethodCall()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (Arguments())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();
                        return true;
                    }
                }

                return false;
            }

            if (_current.Type == TokenType.Assignment ||
                _current.Type == TokenType.AdditionAssignment ||
                _current.Type == TokenType.SubtractionAssignment ||
                _current.Type == TokenType.MultiplicationAssignment ||
                _current.Type == TokenType.DivisionAssignment ||
                _current.Type == TokenType.DivisionRemainderAssignment ||
                _current.Type == TokenType.ShiftLeftAssignment ||
                _current.Type == TokenType.ShiftRightAssignment ||
                _current.Type == TokenType.BitwiseAndAssignment ||
                _current.Type == TokenType.BitwiseOrAssignment ||
                _current.Type == TokenType.BitwiseXorAssignment)
            {
                this.MoveNext();
                if (Expression0())
                    return true;
            }

            return false;
        }

        private bool Arguments()
        {
            if (_end)
                return true;

            if (Expression0())
            {
                if (ArgumentsLine())
                    return true;

                return false;
            }

            return true;
        }

        private bool ArgumentsLine()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Comma)
            {
                this.MoveNext();
                if (Expression0())
                {
                    if (ArgumentsLine())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        #region Expressions

        private bool Expression0()
        {
            if (_end)
                return false;

            if (Expression1())
            {
                if (_current.Type == TokenType.Assignment ||
                    _current.Type == TokenType.AdditionAssignment ||
                    _current.Type == TokenType.SubtractionAssignment ||
                    _current.Type == TokenType.MultiplicationAssignment ||
                    _current.Type == TokenType.DivisionAssignment ||
                    _current.Type == TokenType.DivisionRemainderAssignment ||
                    _current.Type == TokenType.ShiftLeftAssignment ||
                    _current.Type == TokenType.ShiftRightAssignment ||
                    _current.Type == TokenType.BitwiseAndAssignment ||
                    _current.Type == TokenType.BitwiseOrAssignment ||
                    _current.Type == TokenType.BitwiseXorAssignment)
                {
                    this.MoveNext();
                    if (Expression0())
                        return true;
                }

                return true;
            }

            return false;
        }

        private bool Expression1()
        {
            if (_end)
                return false;

            if (Expression2())
            {
                if (Expression1B())
                    return true;

                return false;
            }

            return false;
        }

        private bool Expression1B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Or)
            {
                this.MoveNext();
                if (Expression2())
                {
                    if (Expression1B())
                        return true;

                    return false;
                }
                return false;
            }

            return true;
        }

        private bool Expression2()
        {
            if (_end)
                return false;

            if (Expression3())
            {
                if (Expression2B())
                    return true;
            }

            return false;
        }

        private bool Expression2B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.And)
            {
                this.MoveNext();
                if (Expression3())
                {
                    if (Expression2B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression3()
        {
            if (_end)
                return false;

            if (Expression4())
            {
                if (Expression3B())
                    return true;
            }

            return false;
        }

        private bool Expression3B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseOr)
            {
                this.MoveNext();
                if (Expression4())
                {
                    if (Expression3B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression4()
        {
            if (_end)
                return false;

            if (Expression5())
            {
                if (Expression4B())
                    return true;
            }

            return false;
        }

        private bool Expression4B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseXor)
            {
                this.MoveNext();
                if (Expression5())
                {
                    if (Expression4B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression5()
        {
            if (_end)
                return false;

            if (Expression6())
            {
                if (Expression5B())
                    return true;
            }

            return false;
        }

        private bool Expression5B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseAnd)
            {
                this.MoveNext();
                if (Expression6())
                {
                    if (Expression5B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression6()
        {
            if (_end)
                return false;

            if (Expression7())
            {
                if (Expression6B())
                    return true;
            }

            return false;
        }

        private bool Expression6B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Equality)
            {
                this.MoveNext();
                if (Expression7())
                {
                    if (Expression6B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Inequality)
            {
                this.MoveNext();
                if (Expression7())
                {
                    if (Expression6B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression7()
        {
            if (_end)
                return false;

            if (Expression8())
            {
                if (Expression7B())
                    return true;
            }

            return false;
        }

        private bool Expression7B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.LessThan)
            {
                this.MoveNext();
                if (Expression8())
                {
                    if (Expression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GreaterThan)
            {
                this.MoveNext();
                if (Expression8())
                {
                    if (Expression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.LessThanOrEqual)
            {
                this.MoveNext();
                if (Expression8())
                {
                    if (Expression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GreaterThanOrEqual)
            {
                this.MoveNext();
                if (Expression8())
                {
                    if (Expression7B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression8()
        {
            if (_end)
                return false;

            if (Expression9())
            {
                if (Expression8B())
                    return true;
            }

            return false;
        }

        private bool Expression8B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.ShiftLeft)
            {
                this.MoveNext();
                if (Expression9())
                {
                    if (Expression8B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.ShiftRight)
            {
                this.MoveNext();
                if (Expression9())
                {
                    if (Expression8B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression9()
        {
            if (_end)
                return false;

            if (Expression10())
            {
                if (Expression9B())
                    return true;
            }

            return false;
        }

        private bool Expression9B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Addition)
            {
                this.MoveNext();
                if (Expression10())
                {
                    if (Expression9B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Subtraction)
            {
                this.MoveNext();
                if (Expression10())
                {
                    if (Expression9B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression10()
        {
            if (_end)
                return false;

            if (Expression11())
            {
                if (Expression10B())
                    return true;
            }

            return false;
        }

        private bool Expression10B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Multiplication)
            {
                this.MoveNext();
                if (Expression11())
                {
                    if (Expression10B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Division)
            {
                this.MoveNext();
                if (Expression11())
                {
                    if (Expression10B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.DivisionRemainder)
            {
                this.MoveNext();
                if (Expression11())
                {
                    if (Expression10B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool Expression11()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Addition)
            {
                this.MoveNext();
                //if (Expression12())
                //    return true;
                if (ExpressionSet())
                    return true;
            }

            //if (_current.Type == TokenType.Increment)
            //{
            //    this.MoveNext();
            //    if (Expression12())
            //        return true;
            //}

            if (_current.Type == TokenType.Subtraction)
            {
                this.MoveNext();
                //if (Expression12())
                //    return true;
                if (ExpressionSet())
                    return true;
            }

            //if (_current.Type == TokenType.Decrement)
            //{
            //    this.MoveNext();
            //    if (Expression12())
            //        return true;
            //}

            //if (Expression12())
            //    return true;

            if (_current.Type == TokenType.Not)
            {
                this.MoveNext();
                if (Expression11())
                    return true;
            }

            if (ExpressionSet())
                return true;

            return false;
        }

        private bool Expression12()
        {
            if (_end)
                return false;

            if (ExpressionSet())
            {
                if (_current.Type == TokenType.Increment)
                {
                    this.MoveNext();
                    return true;
                }

                if (_current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    return true;
                }

                return true;
            }

            return false;
        }

        private bool ExpressionSet()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (Expression0())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.IntegerConstant ||
                _current.Type == TokenType.RealConstant ||
                _current.Type == TokenType.True ||
                _current.Type == TokenType.False)
            {
                this.MoveNext();
                return true;
            }

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Increment ||
                    _current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    return true;
                }

                if (_current.Type == TokenType.OpenParentheses)
                {
                    this.MoveNext();
                    if (Arguments())
                    {
                        if (_current.Type == TokenType.CloseParentheses)
                        {
                            this.MoveNext();
                            return true;
                        }

                        return false;
                    }

                    return false;
                }

                return true;
            }

            if (_current.Type == TokenType.Increment ||
                _current.Type == TokenType.Decrement)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    return true;
                }

                return false;
            }

            return false;
        }

        #endregion

        #region ConstantExpressions

        private bool ConstantExpression0()
        {
            if (_end)
                return false;

            if (ConstantExpression1())
            {
                if (_current.Type == TokenType.Assignment ||
                    _current.Type == TokenType.AdditionAssignment ||
                    _current.Type == TokenType.SubtractionAssignment ||
                    _current.Type == TokenType.MultiplicationAssignment ||
                    _current.Type == TokenType.DivisionAssignment ||
                    _current.Type == TokenType.DivisionRemainderAssignment ||
                    _current.Type == TokenType.ShiftLeftAssignment ||
                    _current.Type == TokenType.ShiftRightAssignment ||
                    _current.Type == TokenType.BitwiseAndAssignment ||
                    _current.Type == TokenType.BitwiseOrAssignment ||
                    _current.Type == TokenType.BitwiseXorAssignment)
                {
                    this.MoveNext();
                    if (ConstantExpression0())
                        return true;
                }

                return true;
            }

            return false;
        }

        private bool ConstantExpression1()
        {
            if (_end)
                return false;

            if (ConstantExpression2())
            {
                if (ConstantExpression1B())
                    return true;

                return false;
            }

            return false;
        }

        private bool ConstantExpression1B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Or)
            {
                this.MoveNext();
                if (ConstantExpression2())
                {
                    if (ConstantExpression1B())
                        return true;

                    return false;
                }
                return false;
            }

            return true;
        }

        private bool ConstantExpression2()
        {
            if (_end)
                return false;

            if (ConstantExpression3())
            {
                if (ConstantExpression2B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression2B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.And)
            {
                this.MoveNext();
                if (ConstantExpression3())
                {
                    if (ConstantExpression2B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression3()
        {
            if (_end)
                return false;

            if (ConstantExpression4())
            {
                if (ConstantExpression3B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression3B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseOr)
            {
                this.MoveNext();
                if (ConstantExpression4())
                {
                    if (ConstantExpression3B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression4()
        {
            if (_end)
                return false;

            if (ConstantExpression5())
            {
                if (ConstantExpression4B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression4B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseXor)
            {
                this.MoveNext();
                if (ConstantExpression5())
                {
                    if (ConstantExpression4B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression5()
        {
            if (_end)
                return false;

            if (ConstantExpression6())
            {
                if (ConstantExpression5B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression5B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.BitwiseAnd)
            {
                this.MoveNext();
                if (ConstantExpression6())
                {
                    if (ConstantExpression5B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression6()
        {
            if (_end)
                return false;

            if (ConstantExpression7())
            {
                if (ConstantExpression6B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression6B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Equality)
            {
                this.MoveNext();
                if (ConstantExpression7())
                {
                    if (ConstantExpression6B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Inequality)
            {
                this.MoveNext();
                if (ConstantExpression7())
                {
                    if (ConstantExpression6B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression7()
        {
            if (_end)
                return false;

            if (ConstantExpression8())
            {
                if (ConstantExpression7B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression7B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.LessThan)
            {
                this.MoveNext();
                if (ConstantExpression8())
                {
                    if (ConstantExpression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GreaterThan)
            {
                this.MoveNext();
                if (ConstantExpression8())
                {
                    if (ConstantExpression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.LessThanOrEqual)
            {
                this.MoveNext();
                if (ConstantExpression8())
                {
                    if (ConstantExpression7B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.GreaterThanOrEqual)
            {
                this.MoveNext();
                if (ConstantExpression8())
                {
                    if (ConstantExpression7B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression8()
        {
            if (_end)
                return false;

            if (ConstantExpression9())
            {
                if (ConstantExpression8B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression8B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.ShiftLeft)
            {
                this.MoveNext();
                if (ConstantExpression9())
                {
                    if (ConstantExpression8B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.ShiftRight)
            {
                this.MoveNext();
                if (ConstantExpression9())
                {
                    if (ConstantExpression8B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression9()
        {
            if (_end)
                return false;

            if (ConstantExpression10())
            {
                if (ConstantExpression9B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression9B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Addition)
            {
                this.MoveNext();
                if (ConstantExpression10())
                {
                    if (ConstantExpression9B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Subtraction)
            {
                this.MoveNext();
                if (ConstantExpression10())
                {
                    if (ConstantExpression9B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression10()
        {
            if (_end)
                return false;

            if (ConstantExpression11())
            {
                if (ConstantExpression10B())
                    return true;
            }

            return false;
        }

        private bool ConstantExpression10B()
        {
            if (_end)
                return true;

            if (_current.Type == TokenType.Multiplication)
            {
                this.MoveNext();
                if (ConstantExpression11())
                {
                    if (ConstantExpression10B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Division)
            {
                this.MoveNext();
                if (ConstantExpression11())
                {
                    if (ConstantExpression10B())
                        return true;

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.DivisionRemainder)
            {
                this.MoveNext();
                if (ConstantExpression11())
                {
                    if (ConstantExpression10B())
                        return true;

                    return false;
                }

                return false;
            }

            return true;
        }

        private bool ConstantExpression11()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Addition)
            {
                this.MoveNext();
                //if (ConstantExpression12())
                //    return true;
                if (ConstantExpressionSet())
                    return true;
            }

            //if (_current.Type == TokenType.Increment)
            //{
            //    this.MoveNext();
            //    if (ConstantExpression12())
            //        return true;
            //}

            if (_current.Type == TokenType.Subtraction)
            {
                this.MoveNext();
                //if (ConstantExpression12())
                //    return true;
                if (ConstantExpressionSet())
                    return true;
            }

            //if (_current.Type == TokenType.Decrement)
            //{
            //    this.MoveNext();
            //    if (ConstantExpression12())
            //        return true;
            //}

            //if (ConstantExpression12())
            //    return true;

            if (ConstantExpressionSet())
                return true;

            return false;
        }

        private bool ConstantExpression12()
        {
            if (_end)
                return false;

            if (ConstantExpressionSet())
            {
                if (_current.Type == TokenType.Increment)
                {
                    this.MoveNext();
                    return true;
                }

                if (_current.Type == TokenType.Decrement)
                {
                    this.MoveNext();
                    return true;
                }

                return true;
            }

            return false;
        }

        private bool ConstantExpressionSet()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.OpenParentheses)
            {
                this.MoveNext();
                if (ConstantExpression0())
                {
                    if (_current.Type == TokenType.CloseParentheses)
                    {
                        this.MoveNext();
                        return true;
                    }

                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.IntegerConstant ||
                _current.Type == TokenType.RealConstant)
            {
                this.MoveNext();
                return true;
            }

            return false;
        }

        #endregion

        private void MoveNext()
        {
            if (_currentIndex + 1 >= _tokens.Count)
            {
                try
                {
                    var token = _enumrator.GetNext();
                    if (token == null)
                        _end = true;
                    else
                    {
                        _tokens.Add(token);
                        _currentIndex++;
                    }
                }
                catch (LexicalErrorException)
                {
                    _end = true;
                }
            }
            else
                _currentIndex++;

            if (!_end)
                _current = _tokens[_currentIndex];
        }

        private void SetCurrent(int index)
        {
            _currentIndex = index;
            _current = _tokens[index];
        }

        #endregion

        private bool M()
        {
            if (_end)
                return false;

            return this.Modifier();
        }

        private bool DS()
        {
            if (_end)
                return true;

            if (M())
            {
                if (_current.Type == TokenType.Const)
                {
                    this.MoveNext();

                    if (_current.Type == TokenType.Void)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.Identifier)
                        {
                            this.MoveNext();
                            if (_current.Type == TokenType.OpenParentheses)
                            {
                                this.MoveNext();
                                if (F())
                                {
                                    if (DS())
                                        return true;
                                    return false;
                                }
                                return false;
                            }
                            return false;
                        }
                        return false;
                    }

                    if (_current.Type == TokenType.Unsigned)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.Int ||
                            _current.Type == TokenType.Long)
                        {
                            if (FCV())
                            {
                                if (DS())
                                    return true;
                                return false;
                            }
                            return false;
                        }
                        return false;
                    }

                    if (T())
                    {
                        if (FCV())
                        {
                            if (DS())
                                return true;
                            return false;
                        }
                        return false;
                    }

                    return false;
                }

                if (_current.Type == TokenType.Void)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Identifier)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.OpenParentheses)
                        {
                            this.MoveNext();
                            if (F())
                            {
                                if (DS())
                                    return true;
                                return false;
                            }
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        this.MoveNext();
                        if (FV())
                        {
                            if (DS())
                                return true;
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (FV())
                    {
                        if (DS())
                            return true;
                        return false;
                    }
                    return false;
                }
            }

            if (_current.Type == TokenType.Const)
            {
                this.MoveNext();

                if (_current.Type == TokenType.Void)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Identifier)
                    {
                        this.MoveNext();
                        if (_current.Type == TokenType.OpenParentheses)
                        {
                            this.MoveNext();
                            if (F())
                            {
                                if (DS())
                                    return true;
                                return false;
                            }
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (_current.Type == TokenType.Unsigned)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.Int ||
                        _current.Type == TokenType.Long)
                    {
                        if (FCV())
                        {
                            if (DS())
                                return true;
                            return false;
                        }
                        return false;
                    }
                    return false;
                }

                if (T())
                {
                    if (FCV())
                    {
                        if (DS())
                            return true;
                        return false;
                    }
                    return false;
                }

                return false;
            }

            if (_current.Type == TokenType.Void)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Identifier)
                {
                    this.MoveNext();
                    if (_current.Type == TokenType.OpenParentheses)
                    {
                        this.MoveNext();
                        if (F())
                        {
                            if (DS())
                                return true;
                            return false;
                        }
                        return false;
                    }
                    return false;
                }
                return false;
            }

            if (_current.Type == TokenType.Unsigned)
            {
                this.MoveNext();
                if (_current.Type == TokenType.Int ||
                    _current.Type == TokenType.Long)
                {
                    this.MoveNext();
                    if (FV())
                    {
                        if (DS())
                            return true;
                        return false;
                    }
                    return false;
                }
                return false;
            }

            if (T())
            {
                if (FV())
                {
                    if (DS())
                        return true;
                    return false;
                }
                return false;
            }

            return true;
        }

        private bool T()
        {
            if (_end)
                return false;

            return Type();
        }

        private bool FV()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.OpenParentheses)
                {
                    this.MoveNext();
                    if (F())
                        return true;
                    return false;
                }

                if (D())
                {
                    if (V())
                        return true;
                    return false;
                }

                return false;
            }

            return false;
        }

        private bool FCV()
        {
            if (_end)
                return false;

            if (_current.Type == TokenType.Identifier)
            {
                this.MoveNext();
                if (_current.Type == TokenType.OpenParentheses)
                {
                    this.MoveNext();
                    if (F())
                        return true;
                    return false;
                }

                if (CD())
                {
                    if (V())
                        return true;
                    return false;
                }

                return false;
            }

            return false;
        }

        private bool D()
        {
            if (_end)
                return false;

            return Declaration();
        }

        private bool CD()
        {
            if (_end)
                return false;

            return ConstDeclaration();
        }

        private bool F()
        {
            if (_end)
                return false;

            return FunctionDeclaration();
        }

        private bool V()
        {
            if (_end)
                return false;

            if (IdentifierDeclarationsSetLine())
            {
                if (_current.Type == TokenType.Semicolon)
                {
                    this.MoveNext();
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}
